<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>极速在线图片格式转换器</title>
    <style>
      @import url('./format/css2.css');

      :root {
        /* 拟态风格颜色变量 */
        --primary: #667eea;
        --primary-rgb: 102, 126, 234;
        --secondary: #764ba2;
        --background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        --card: #f0f0f3;
        --text-primary: #2d3748;
        --text-secondary: #4a5568;
        --text-muted: #718096;
        --border: #e2e8f0;

        /* 阴影定义 */
        --shadow-inset: inset 6px 6px 12px #d1d9e6, inset -6px -6px 12px #ffffff;
        --shadow-outset: 6px 6px 12px #d1d9e6, -6px -6px 12px #ffffff;
        --shadow-medium: 3px 3px 6px #d1d9e6, -3px -3px 6px #ffffff;
        --shadow-small: 2px 2px 4px #d1d9e6, -2px -2px 4px #ffffff;
        --shadow-light: rgba(255, 255, 255, 0.8);

        /* 边框圆角 */
        --border-radius: 16px;
        --border-radius-small: 8px;
        --border-radius-large: 24px;

        /* 过渡效果 */
        --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      }

      /* 动画关键帧 */
      @keyframes fadeIn {
        from {
          opacity: 0;
          transform: translateY(20px);
        }
        to {
          opacity: 1;
          transform: translateY(0);
        }
      }

      @keyframes containerFloat {
        0%,
        100% {
          transform: translateY(0px);
        }
        50% {
          transform: translateY(-5px);
        }
      }

      @keyframes headerShine {
        0% {
          background-position: -200% center;
        }
        100% {
          background-position: 200% center;
        }
      }

      @keyframes titlePulse {
        0%,
        100% {
          transform: scale(1);
        }
        50% {
          transform: scale(1.02);
        }
      }

      @keyframes iconPulse {
        0%,
        100% {
          transform: scale(1);
          opacity: 0.8;
        }
        50% {
          transform: scale(1.1);
          opacity: 1;
        }
      }

      @keyframes slideIn {
        from {
          opacity: 0;
          transform: translateX(-20px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

      @keyframes shimmer {
        0% {
          background-position: -200% center;
        }
        100% {
          background-position: 200% center;
        }
      }

      * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
          Roboto, sans-serif;
      }

      body {
        color: var(--text-primary);
        min-height: 100vh;
        padding: 20px;
        font-weight: 400;
        line-height: 1.6;
        animation: fadeIn 0.8s ease-out;
      }

      .container {
        max-width: 1200px;
        margin: 0 auto;
        background: var(--card);
        border-radius: var(--border-radius-large);
        box-shadow: var(--shadow-outset);
        overflow: hidden;
        animation: containerFloat 6s ease-in-out infinite;
        position: relative;
      }

      .container::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        height: 4px;
        background: linear-gradient(
          90deg,
          var(--primary),
          var(--secondary),
          var(--primary)
        );
        background-size: 200% 100%;
        animation: headerShine 3s ease-in-out infinite;
      }

      header {
        text-align: center;
        padding: 40px 30px;
        background: linear-gradient(
          135deg,
          rgba(255, 255, 255, 0.1),
          rgba(255, 255, 255, 0.05)
        );
        border-bottom: 1px solid var(--border);
        position: relative;
      }

      h1 {
        font-size: 2.8rem;
        font-weight: 700;
        margin-bottom: 16px;
        background: linear-gradient(135deg, var(--primary), var(--secondary));
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        background-clip: text;
        animation: titlePulse 4s ease-in-out infinite;
        letter-spacing: -0.02em;
      }

      .subtitle {
        font-size: 1.1rem;
        color: var(--text-secondary);
        max-width: 600px;
        margin: 0 auto;
        line-height: 1.7;
        font-weight: 400;
        opacity: 0.9;
      }

      .main-content {
        display: grid;
        grid-template-columns: 1fr 1fr;
        padding: 30px;
        gap: 30px;
        animation: contentSlideUp 0.8s ease-out 0.2s both;
      }

      .upload-panel,
      .settings-panel {
        background: var(--card);
        border-radius: var(--border-radius);
        padding: 30px;
        box-shadow: var(--shadow-medium);
        transition: var(--transition);
        position: relative;
        overflow: hidden;
      }

      .upload-panel::before,
      .settings-panel::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.1),
          transparent
        );
        transition: var(--transition);
      }

      .upload-panel:hover::before,
      .settings-panel:hover::before {
        left: 100%;
      }

      .upload-panel:hover,
      .settings-panel:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-outset);
      }

      .panel-title {
        font-size: 1.6rem;
        font-weight: 600;
        margin-bottom: 24px;
        color: var(--primary);
        display: flex;
        align-items: center;
        gap: 12px;
        letter-spacing: -0.01em;
      }

      .panel-title .emoji {
        font-size: 1.8rem;
        animation: iconFloat 3s ease-in-out infinite;
      }

      .file-upload-area {
        border: 2px dashed var(--primary);
        border-radius: var(--border-radius);
        padding: 40px 20px;
        text-align: center;
        cursor: pointer;
        transition: var(--transition);
        margin-bottom: 24px;
        position: relative;
        background: linear-gradient(
          135deg,
          rgba(102, 126, 234, 0.05),
          rgba(118, 75, 162, 0.05)
        );
        box-shadow: var(--shadow-inset);
      }

      .file-upload-area::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 0;
        height: 0;
        background: radial-gradient(
          circle,
          rgba(102, 126, 234, 0.1),
          transparent
        );
        border-radius: 50%;
        transform: translate(-50%, -50%);
        transition: var(--transition);
      }

      .file-upload-area:hover {
        border-color: var(--secondary);
        transform: translateY(-3px);
        box-shadow: var(--shadow-outset);
      }

      .file-upload-area:hover::before {
        width: 200px;
        height: 200px;
      }

      .file-upload-area p {
        margin: 12px 0;
        font-size: 1rem;
        color: var(--text-secondary);
        font-weight: 500;
        position: relative;
        z-index: 1;
      }

      .file-upload-area p:first-of-type {
        font-weight: 600;
        color: var(--text-primary);
      }

      .upload-icon {
        font-size: 48px;
        color: var(--primary);
        margin-bottom: 16px;
        animation: iconPulse 2s ease-in-out infinite;
        position: relative;
        z-index: 1;
      }

      input[type='file'] {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        opacity: 0;
        cursor: pointer;
        z-index: 2;
      }

      .format-options {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
        gap: 16px;
        margin: 24px 0;
      }

      .format-option {
        background: var(--card);
        border-radius: var(--border-radius-small);
        padding: 16px 12px;
        text-align: center;
        cursor: pointer;
        transition: var(--transition);
        border: 2px solid transparent;
        box-shadow: var(--shadow-small);
        font-weight: 600;
        color: var(--text-primary);
        position: relative;
        overflow: hidden;
      }

      .format-option::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(102, 126, 234, 0.1),
          transparent
        );
        transition: var(--transition);
      }

      .format-option:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-medium);
      }

      .format-option:hover::before {
        left: 100%;
      }

      .format-option.active {
        background: linear-gradient(135deg, var(--primary), var(--secondary));
        color: white;
        border-color: var(--primary);
        box-shadow: var(--shadow-outset);
      }

      .format-option.active::before {
        background: linear-gradient(
          90deg,
          transparent,
          rgba(255, 255, 255, 0.2),
          transparent
        );
      }

      .section-title {
        font-size: 1.1rem;
        font-weight: 600;
        color: var(--text-primary);
        margin: 24px 0 16px 0;
        letter-spacing: -0.01em;
      }

      .quality-control {
        margin: 24px 0;
      }

      .quality-slider {
        width: 100%;
        margin: 16px 0;
        -webkit-appearance: none;
        height: 8px;
        border-radius: 4px;
        background: var(--card);
        box-shadow: var(--shadow-inset);
        outline: none;
        transition: var(--transition);
      }

      .quality-slider::-webkit-slider-thumb {
        -webkit-appearance: none;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: linear-gradient(135deg, var(--primary), var(--secondary));
        cursor: pointer;
        box-shadow: var(--shadow-small);
        transition: var(--transition);
      }

      .quality-slider::-webkit-slider-thumb:hover {
        transform: scale(1.1);
        box-shadow: var(--shadow-medium);
      }

      .preview-container {
        background: var(--card);
        border-radius: var(--border-radius);
        overflow: hidden;
        margin-top: 24px;
        aspect-ratio: 16/9;
        display: flex;
        align-items: center;
        justify-content: center;
        box-shadow: var(--shadow-inset);
        border: 1px solid rgba(102, 126, 234, 0.1);
        padding: 16px;
        color: var(--text-secondary);
        font-weight: 500;
      }

      .preview-container img {
        max-width: 100%;
        max-height: 100%;
        display: block;
        border-radius: var(--border-radius-small);
        box-shadow: var(--shadow-small);
        transition: var(--transition);
      }

      .preview-container img:hover {
        transform: scale(1.02);
        box-shadow: var(--shadow-medium);
      }

      .file-list {
        max-height: 300px;
        overflow-y: auto;
        margin-top: 24px;
        background: var(--card);
        border-radius: var(--border-radius);
        padding: 16px;
        box-shadow: var(--shadow-inset);
        border: 1px solid rgba(102, 126, 234, 0.1);
      }

      .file-item {
        display: flex;
        justify-content: space-between;
        padding: 16px;
        background: var(--card);
        border-radius: var(--border-radius-small);
        margin-bottom: 12px;
        align-items: center;
        transition: var(--transition);
        box-shadow: var(--shadow-small);
        border: 1px solid rgba(102, 126, 234, 0.1);
        position: relative;
        overflow: hidden;
      }

      .file-item::before {
        content: '';
        position: absolute;
        top: 0;
        left: -100%;
        width: 100%;
        height: 100%;
        background: linear-gradient(
          90deg,
          transparent,
          rgba(102, 126, 234, 0.05),
          transparent
        );
        transition: var(--transition);
      }

      .file-item:hover {
        transform: translateX(3px);
        box-shadow: var(--shadow-medium);
        border-color: var(--primary);
      }

      .file-item:hover::before {
        left: 100%;
      }

      .file-info {
        display: flex;
        align-items: center;
        gap: 12px;
        position: relative;
        z-index: 1;
      }

      .file-icon {
        width: 32px;
        height: 32px;
        font-size: 1.5rem;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .file-name {
        max-width: 200px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        font-weight: 600;
        color: var(--text-primary);
        font-size: 0.95rem;
      }

      .file-size {
        font-size: 0.85rem;
        color: var(--text-secondary);
        font-weight: 500;
      }

      .file-status {
        font-size: 0.9rem;
        color: var(--primary);
        font-weight: 600;
        position: relative;
        z-index: 1;
      }

      .actions {
        display: flex;
        gap: 16px;
        margin-top: 32px;
        flex-wrap: wrap;
      }

      button {
        flex: 1;
        min-width: 140px;
        background: linear-gradient(135deg, var(--primary), var(--secondary));
        color: white;
        border: none;
        padding: 16px 24px;
        border-radius: var(--border-radius);
        cursor: pointer;
        font-weight: 600;
        font-size: 0.95rem;
        transition: var(--transition);
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        text-transform: uppercase;
        letter-spacing: 0.5px;
        position: relative;
        overflow: hidden;
        box-shadow: var(--shadow-medium);
      }

      button::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 0;
        height: 0;
        background: rgba(255, 255, 255, 0.2);
        border-radius: 50%;
        transform: translate(-50%, -50%);
        transition: var(--transition);
      }

      button:hover::before {
        width: 300px;
        height: 300px;
      }

      button:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-outset);
      }

      button:active {
        transform: translateY(0);
        box-shadow: var(--shadow-small);
      }

      button:disabled {
        background: var(--card);
        color: var(--text-muted);
        cursor: not-allowed;
        transform: none;
        box-shadow: var(--shadow-inset);
        opacity: 0.5;
      }

      button:disabled::before {
        display: none;
      }

      .btn-reset {
        background: linear-gradient(135deg, #ff6b6b, #ff5252);
      }

      .btn-reset:hover {
        box-shadow: 0 8px 25px rgba(255, 107, 107, 0.4);
      }

      .conversion-info {
        margin-top: 30px;
        padding: 20px;
        background: rgba(0, 30, 60, 0.5);
        border-radius: 15px;
      }

      .info-title {
        font-size: 1.5rem;
        margin-bottom: 15px;
        color: #00f2fe;
      }

      .info-content {
        line-height: 1.8;
        color: #c0e0ff;
      }

      .features {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
        gap: 20px;
        margin-top: 20px;
      }

      .feature {
        background: rgba(255, 255, 255, 0.05);
        padding: 20px;
        border-radius: 10px;
        border-left: 3px solid #4facfe;
        color: #fff;
      }

      .feature h3 {
        color: #4facfe;
        margin-bottom: 10px;
      }

      footer {
        text-align: center;
        padding: 30px;
        color: #a0d2ff;
        font-size: 0.9rem;
        border-top: 1px solid rgba(255, 255, 255, 0.1);
      }

      /* 响应式设计 */
      @media (max-width: 1024px) {
        .container {
          padding: 20px;
          margin: 20px;
        }

        .main-content {
          gap: 20px;
        }

        .upload-panel,
        .settings-panel {
          padding: 20px;
        }
      }

      @media (max-width: 768px) {
        body {
          padding: 0;
        }

        .container {
          margin: 10px;
          padding: 16px;
          border-radius: 16px;
        }

        .main-content {
          grid-template-columns: 1fr;
          gap: 16px;
        }

        .upload-panel,
        .settings-panel {
          padding: 16px;
        }

        .file-upload-area {
          padding: 24px 16px;
        }

        .upload-icon {
          font-size: 36px;
        }

        .format-options {
          grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
          gap: 12px;
        }

        .format-option {
          padding: 12px 8px;
          font-size: 0.85rem;
        }

        .actions {
          flex-direction: column;
          gap: 12px;
        }

        button {
          min-width: auto;
          padding: 14px 20px;
          font-size: 0.9rem;
        }

        .file-item {
          padding: 12px;
        }

        .preview-container {
          padding: 16px;
        }

        h1 {
          font-size: 2.2rem;
        }
      }

      @media (max-width: 480px) {
        body {
          padding: 0;
        }

        .container {
          margin: 5px;
          padding: 12px;
        }

        h1 {
          font-size: 1.8rem;
        }

        .subtitle {
          font-size: 0.9rem;
        }

        .upload-panel,
        .settings-panel {
          padding: 12px;
        }

        .file-upload-area {
          padding: 20px 12px;
        }

        .upload-icon {
          font-size: 32px;
        }

        .format-options {
          grid-template-columns: repeat(2, 1fr);
        }

        button {
          padding: 12px 16px;
          font-size: 0.85rem;
        }

        .section-title {
          font-size: 1rem;
        }

        .file-name {
          font-size: 0.9rem;
        }

        .file-size {
          font-size: 0.8rem;
        }
      }
    </style>
  </head>
  <body>
    <div class="container">
      <header>
        <h1>极速在线图片格式转换</h1>
        <p class="subtitle">
          无需上传服务器 · 100%本地浏览器处理 · 支持批量转换 · 完美保护隐私
        </p>
      </header>

      <div class="main-content">
        <div class="upload-panel">
          <h2 class="panel-title">📁 图片上传</h2>

          <div class="file-upload-area" id="dropArea">
            <div class="upload-icon">📁</div>
            <p>拖放图片到此处 或 <u>点击选择文件</u></p>
            <p>支持 JPG, PNG, WEBP, BMP, SVG, GIF 等格式</p>
            <input type="file" id="fileInput" accept="image/*" multiple />
          </div>

          <div class="file-list" id="fileList">
            <p style="text-align: center; padding: 20px">暂无上传文件</p>
          </div>
        </div>

        <div class="settings-panel">
          <h2 class="panel-title">⚙️ 转换设置</h2>

          <h3 class="section-title">目标格式</h3>
          <div class="format-options">
            <div class="format-option active" data-format="jpg">
              <div>JPG</div>
            </div>
            <div class="format-option" data-format="png">
              <div>PNG</div>
            </div>
            <div class="format-option" data-format="webp">
              <div>WEBP</div>
            </div>
            <div class="format-option" data-format="bmp">
              <div>BMP</div>
            </div>
            <div class="format-option" data-format="svg">
              <div>SVG</div>
            </div>
            <div class="format-option" data-format="gif">
              <div>GIF</div>
            </div>
          </div>

          <div class="quality-control">
            <h3 class="section-title">
              输出质量 <span id="qualityValue">90%</span>
            </h3>
            <input
              type="range"
              min="10"
              max="100"
              value="90"
              class="quality-slider"
              id="qualitySlider"
            />
            <p style="color: #aaa; font-size: 0.9rem">
              提示：仅JPG/WEBP支持质量调整，PNG/SVG/GIF为无损格式
            </p>
            <p style="color: #ff6b6b; font-size: 0.85rem; margin-top: 8px">
              ⚠️ GIF动画说明：GIF转GIF保持动画，GIF转其他格式仅保留第一帧
            </p>
          </div>

          <div class="preview-container" id="previewContainer">
            <p>图片预览区</p>
          </div>

          <div class="actions">
            <button id="convertBtn">🔄 开始转换</button>
            <button id="downloadBtn" disabled>💾 全部下载</button>
            <button id="resetBtn" class="btn-reset">❌ 重置</button>
          </div>
        </div>
      </div>

      <div class="conversion-info">
        <h2 class="info-title">✨ 功能特点</h2>
        <div class="features">
          <div class="feature">
            <h3>完全本地处理</h3>
            <p>
              所有图片处理均在浏览器中完成，无需上传到任何服务器，100%保护您的隐私安全[4,5](@ref)。
            </p>
          </div>
          <div class="feature">
            <h3>批量高效转换</h3>
            <p>支持同时上传多张图片批量转换，大幅提升工作效率[1,6](@ref)。</p>
          </div>
          <div class="feature">
            <h3>格式全面支持</h3>
            <p>支持JPG、PNG、WEBP、BMP、SVG等主流图片格式互转[2,7](@ref)。</p>
          </div>
          <div class="feature">
            <h3>大文件兼容</h3>
            <p>可处理高达50MB的图片文件，满足专业需求[1,4](@ref)。</p>
          </div>
        </div>
      </div>

      <footer>
        <p>
          © 2025 极速图片格式转换器 | 基于HTML5 Canvas技术实现 | 永久免费无广告
        </p>
        <p>
          隐私声明：本工具不会收集任何用户上传的图片内容，所有处理均在您的浏览器中完成
        </p>
      </footer>
    </div>

    <script>
      // 全局变量
      let uploadedFiles = []
      let currentFormat = 'jpg'
      let currentQuality = 90

      // DOM元素
      const fileInput = document.getElementById('fileInput')
      const dropArea = document.getElementById('dropArea')
      const fileList = document.getElementById('fileList')
      const formatOptions = document.querySelectorAll('.format-option')
      const qualitySlider = document.getElementById('qualitySlider')
      const qualityValue = document.getElementById('qualityValue')
      const convertBtn = document.getElementById('convertBtn')
      const downloadBtn = document.getElementById('downloadBtn')
      const resetBtn = document.getElementById('resetBtn')
      const previewContainer = document.getElementById('previewContainer')

      // 初始化事件
      function initEvents() {
        // 文件选择处理
        fileInput.addEventListener('change', handleFileSelect)

        // 拖放功能
        dropArea.addEventListener('dragover', (e) => {
          e.preventDefault()
          dropArea.style.borderColor = '#00f2fe'
          dropArea.style.backgroundColor = 'rgba(0, 242, 254, 0.1)'
        })

        dropArea.addEventListener('dragleave', () => {
          dropArea.style.borderColor = '#5d9cec'
          dropArea.style.backgroundColor = 'rgba(93, 156, 236, 0.05)'
        })

        dropArea.addEventListener('drop', (e) => {
          e.preventDefault()
          dropArea.style.borderColor = '#5d9cec'
          dropArea.style.backgroundColor = 'rgba(93, 156, 236, 0.05)'

          if (e.dataTransfer.files.length) {
            handleFiles(e.dataTransfer.files)
          }
        })

        // 格式选择
        formatOptions.forEach((option) => {
          option.addEventListener('click', () => {
            formatOptions.forEach((opt) => opt.classList.remove('active'))
            option.classList.add('active')
            currentFormat = option.dataset.format
          })
        })

        // 质量滑块
        qualitySlider.addEventListener('input', () => {
          currentQuality = qualitySlider.value
          qualityValue.textContent = `${currentQuality}%`
        })

        // 转换按钮
        convertBtn.addEventListener('click', convertImages)

        // 下载按钮
        downloadBtn.addEventListener('click', downloadAll)

        // 重置按钮
        resetBtn.addEventListener('click', resetAll)
      }

      // 处理选择的文件
      function handleFileSelect(e) {
        handleFiles(e.target.files)
      }

      // 处理文件
      function handleFiles(files) {
        for (let i = 0; i < files.length; i++) {
          const file = files[i]

          // 检查文件类型
          if (!file.type.match('image.*')) {
            alert(`"${file.name}" 不是图片文件，已跳过`)
            continue
          }

          // 添加到文件列表
          uploadedFiles.push({
            file: file,
            status: '待转换',
            converted: null,
          })

          // 如果是第一个文件，显示预览
          if (i === 0) {
            showPreview(file)
          }
        }

        updateFileList()
      }

      // 显示预览
      function showPreview(file) {
        const reader = new FileReader()
        reader.onload = (e) => {
          previewContainer.innerHTML = `<img src="${e.target.result}" alt="预览">`
        }
        reader.readAsDataURL(file)
      }

      // 更新文件列表显示
      function updateFileList() {
        if (uploadedFiles.length === 0) {
          fileList.innerHTML =
            '<p style="text-align: center; padding: 20px;">暂无上传文件</p>'
          return
        }

        fileList.innerHTML = ''
        uploadedFiles.forEach((fileInfo, index) => {
          const file = fileInfo.file
          const item = document.createElement('div')
          item.className = 'file-item'

          const extension = file.name.split('.').pop().toUpperCase()
          const size = formatFileSize(file.size)

          item.innerHTML = `
                    <div class="file-info">
                        <div class="file-icon">📷</div>
                        <div>
                            <div class="file-name">${file.name}</div>
                            <div class="file-size">${extension} | ${size}</div>
                        </div>
                    </div>
                    <div class="file-status">${fileInfo.status}</div>
                `

          fileList.appendChild(item)
        })

        convertBtn.disabled = false
      }

      // 转换图片
      async function convertImages() {
        if (uploadedFiles.length === 0) {
          alert('请先上传图片')
          return
        }

        convertBtn.disabled = true
        convertBtn.textContent = '转换中...'

        // 转换所有图片
        for (let i = 0; i < uploadedFiles.length; i++) {
          const fileInfo = uploadedFiles[i]
          fileInfo.status = '转换中...'
          updateFileList()

          try {
            // 检查是否为GIF转其他格式的情况
            const isGifToOther =
              fileInfo.file.type === 'image/gif' && currentFormat !== 'gif'
            if (isGifToOther) {
              fileInfo.status = '转换中...(动画将丢失)'
              updateFileList()
            }

            const convertedBlob = await convertImage(
              fileInfo.file,
              currentFormat,
              currentQuality
            )
            fileInfo.converted = {
              blob: convertedBlob,
              url: URL.createObjectURL(convertedBlob),
              name:
                fileInfo.file.name.replace(/\.[^/.]+$/, '') +
                '.' +
                currentFormat,
            }

            if (isGifToOther) {
              fileInfo.status = '✓ 转换完成(静态图片)'
            } else {
              fileInfo.status = '✓ 转换完成'
            }
          } catch (error) {
            console.error(error)
            fileInfo.status = '✗ 转换失败'
          }

          updateFileList()

          // 显示第一张转换完成的图片预览
          if (i === 0 && fileInfo.converted) {
            previewContainer.innerHTML = `<img src="${fileInfo.converted.url}" alt="转换预览">`
          }
        }

        convertBtn.textContent = '🔄 开始转换'
        downloadBtn.disabled = false
      }

      // 图片转换核心函数
      function convertImage(file, format, quality) {
        return new Promise((resolve, reject) => {
          // 检查是否为GIF文件
          const isGif = file.type === 'image/gif'

          // 如果是GIF转GIF，直接返回原文件以保持动画
          if (isGif && format === 'gif') {
            resolve(file)
            return
          }

          // 如果是GIF转其他格式，给出警告但继续处理（只转换第一帧）
          if (isGif && format !== 'gif') {
            console.warn('GIF动画将被转换为静态图片（仅保留第一帧）')
          }

          const img = new Image()
          const reader = new FileReader()

          reader.onload = (e) => {
            img.onload = () => {
              // 创建Canvas进行转换
              const canvas = document.createElement('canvas')
              canvas.width = img.width
              canvas.height = img.height

              const ctx = canvas.getContext('2d')
              ctx.drawImage(img, 0, 0)

              // 根据格式转换
              let mimeType
              switch (format) {
                case 'jpg':
                case 'jpeg':
                  mimeType = 'image/jpeg'
                  break
                case 'png':
                  mimeType = 'image/png'
                  break
                case 'webp':
                  mimeType = 'image/webp'
                  break
                case 'bmp':
                  mimeType = 'image/bmp'
                  break
                case 'gif':
                  // 对于非GIF源文件转GIF，使用静态转换
                  mimeType = 'image/gif'
                  break
                case 'svg':
                  // SVG格式需要特殊处理
                  const svgData = createSVGFromCanvas(canvas)
                  const svgBlob = new Blob([svgData], { type: 'image/svg+xml' })
                  resolve(svgBlob)
                  return
                default:
                  mimeType = 'image/jpeg'
              }

              // 转换质量处理
              let qualityValue = quality / 100
              if (format === 'png' || format === 'svg' || format === 'gif') {
                // PNG、SVG和GIF格式不支持质量参数
                qualityValue = undefined
              }

              canvas.toBlob(
                (blob) => {
                  if (blob) {
                    resolve(blob)
                  } else {
                    reject(new Error('图片转换失败'))
                  }
                },
                mimeType,
                qualityValue
              )
            }

            img.onerror = () => {
              reject(new Error('图片加载失败'))
            }

            img.src = e.target.result
          }

          reader.onerror = () => {
            reject(new Error('文件读取失败'))
          }

          reader.readAsDataURL(file)
        })
      }

      // 下载所有转换后的图片
      function downloadAll() {
        if (!uploadedFiles.some((file) => file.converted)) {
          alert('没有可下载的转换结果')
          return
        }

        // 创建并触发下载
        uploadedFiles.forEach((fileInfo) => {
          if (fileInfo.converted) {
            const a = document.createElement('a')
            a.href = fileInfo.converted.url
            a.download = fileInfo.converted.name
            document.body.appendChild(a)
            a.click()
            document.body.removeChild(a)
          }
        })
      }

      // 重置所有
      function resetAll() {
        // 释放对象URL
        uploadedFiles.forEach((fileInfo) => {
          if (fileInfo.converted) {
            URL.revokeObjectURL(fileInfo.converted.url)
          }
        })

        uploadedFiles = []
        fileInput.value = ''
        previewContainer.innerHTML = '<p>图片预览区</p>'
        convertBtn.disabled = true
        downloadBtn.disabled = true
        updateFileList()
      }

      // 创建SVG从Canvas
      function createSVGFromCanvas(canvas) {
        const dataURL = canvas.toDataURL('image/png')
        const svgContent = `<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${canvas.width}" height="${canvas.height}" viewBox="0 0 ${canvas.width} ${canvas.height}">
  <image width="${canvas.width}" height="${canvas.height}" xlink:href="${dataURL}"/>
</svg>`
        return svgContent
      }

      // 格式化文件大小
      function formatFileSize(bytes) {
        if (bytes < 1024) return bytes + ' B'
        else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB'
        else return (bytes / 1048576).toFixed(1) + ' MB'
      }

      // 初始化
      window.onload = initEvents
    </script>
  </body>
</html>
